#include "Point2D.h"

//#ifdef _STROKE_H
/*
//----------Stroke::countWordInString---------------
int Stroke::countWordInString(char *str, char *strWord)
{
	char *pch;
	pch = strstr(str, strWord);
	int iCount = 0;

	while(pch)
	{
		iCount++;
		pch = strstr(pch + strlen(strWord), strWord);
	}
	return iCount;
}

//----------------Stroke::findPositionInString-----------------
int* Stroke::findPositionInString(char *str, char *strWord, int &iLenArr)
{
	iLenArr = countWordInString(str, strWord);
	int *arr = new int [iLenArr];

	char *pch;
	pch = strstr(str, strWord);
	int iCount = 0;
	
	while(pch)
	{
		arr [iCount] = pch - str;
		++iCount;
		pch = strstr(pch + strlen(strWord), strWord);
	}

	return arr;
}
*/
///-----------Stroke::ReadFile-------
void Stroke::ReadFile(char* strFilePath)
{
	std::ifstream ifstr (strFilePath);
	if (!ifstr)
	{
		printf("cannot open file");
		return;
	}
	char buff_tmp[100];
	ifstr>>buff_tmp;
	int i = 0;
	while(!ifstr.eof())
	{
		
		if (isdigit(buff_tmp[0]))//digit, note move it to first 'if' to optimize 
		{
			m_arrayPoint[i].x = atof(buff_tmp);
			ifstr>>m_arrayPoint[i].y;
			m_arrayPoint[i].m_penType = Point2D::PEN_TYPE::PEN_MOVE;
		}
		else if (strncmp(buff_tmp, ".PEN_DOWN", 9)==0)
		{
			m_arrayPoint[i].x = 0.0;
			m_arrayPoint[i].y = 0.0;
			m_arrayPoint[i].m_penType = Point2D::PEN_TYPE::PEN_DOWN;
		}
		else if (strncmp(buff_tmp, ".PEN_UP", 7)==0)
		{
			m_arrayPoint[i].x = 1.0;
			m_arrayPoint[i].y = 1.0;
			m_arrayPoint[i].m_penType = Point2D::PEN_TYPE::PEN_UP;
		}

		ifstr>>buff_tmp;
		++i;
	}
	ifstr.close();
	n = i;
	printf("n = %d\n" , n);
	for ( i = 0; i < n; ++i)
	{
		printf("%.2f %.2f\n", m_arrayPoint[i].x, m_arrayPoint[i].y);
	}
	
}

float Stroke::std(bool isX_Or_Y)//true for x, false for y
{
	int itmp_n = 0;
	int i;
	float iAverage = 0, iAverageSqr = 0;
	if ( isX_Or_Y) //true for X
	{
		for (i = 0; i < n; ++i)
		{
			if (m_arrayPoint[i].m_penType == Point2D::PEN_TYPE::PEN_MOVE)
			{
				++itmp_n;
				iAverage += m_arrayPoint[i].x;
				iAverageSqr += m_arrayPoint[i].x * m_arrayPoint[i].x;
			}
		}
	}
	else // false for Y
	{
		for (i = 0; i < n; ++i)
		{
			if (m_arrayPoint[i].m_penType == Point2D::PEN_TYPE::PEN_MOVE)
			{
				++itmp_n;
				iAverage += m_arrayPoint[i].y;
				iAverageSqr += m_arrayPoint[i].y * m_arrayPoint[i].y;
			}
		}
	}

	float fl_var = ( float(iAverageSqr)/itmp_n - (float(iAverage)/itmp_n) * (float(iAverage)/itmp_n) ) * itmp_n / (itmp_n - 1);
	return sqrt(fl_var);
}

float Stroke::MinX()
{
	float min;
	int i;
	for (i = 0; i < n; ++i)
	{
		if (m_arrayPoint[i].m_penType == Point2D::PEN_TYPE::PEN_MOVE)
		{
			min = m_arrayPoint[i].x;
			break;
		}
	}//end i

	for (i = 0; i < n; ++i)
	{
		if (m_arrayPoint[i].m_penType == Point2D::PEN_TYPE::PEN_MOVE)
		{
			if (min > m_arrayPoint[i].x)
				min = m_arrayPoint[i].x;	
		}
	}//end i
	return min;
}
float Stroke::MinY()
{
	float min;
	int i;
	for (i = 0; i < n; ++i)
	{
		if (m_arrayPoint[i].m_penType == Point2D::PEN_TYPE::PEN_MOVE)
		{
			min = m_arrayPoint[i].y;
			break;
		}
	}//end i

	for (i = 0; i < n; ++i)
	{
		if (m_arrayPoint[i].m_penType == Point2D::PEN_TYPE::PEN_MOVE)
		{
			if (min > m_arrayPoint[i].y)
				min = m_arrayPoint[i].y;	
		}
	}//end i
	return min;
}

void Stroke::Normalize()
{
	int i; 
	float fl_minX, fl_minY;
	fl_minX = MinX();
	fl_minY = MinY();
	
	float fl_stdY = std(false);//false for y
	if (fl_stdY == 0) fl_stdY =1;
	for (i = 0; i < n; ++i)
	{
		if (m_arrayPoint[i].m_penType == Point2D::PEN_TYPE::PEN_MOVE)
		{
			m_arrayPoint[i].x = (m_arrayPoint[i].x - fl_minX) / fl_stdY;
			m_arrayPoint[i].y = (m_arrayPoint[i].y - fl_minY) / fl_stdY;
		}
	}//end i

}

void Stroke::ReSampleLinear(float d_len)
{
	int i;
	float dX, dY, dist;
	int iPointNeedAdd;
	std::list<Point2D> ls_tmp;
	Point2D pt_tmp;
	pt_tmp.m_penType = Point2D::PEN_TYPE::PEN_MOVE;
	for (i = 0; i < n; ++i)
	{
		if (m_arrayPoint[i].m_penType == Point2D::PEN_TYPE::PEN_MOVE)
		{
			if (m_arrayPoint[i+1].m_penType == Point2D::PEN_TYPE::PEN_MOVE)
			{
				dX = m_arrayPoint[i+1].x - m_arrayPoint[i].x;
				dY = m_arrayPoint[i+1].y - m_arrayPoint[i].y;
				dist = sqrt(dX * dX + dY * dY);
				if (dist > 0)
				{
					iPointNeedAdd = floor(dist / d_len - d_len / 1000);
					int j;
					if (iPointNeedAdd > 0)
					{
						for (j = 0;j < iPointNeedAdd; ++j)
						{
							pt_tmp.x = m_arrayPoint[i].x + j * dX / iPointNeedAdd;
							pt_tmp.y = m_arrayPoint[i].y + j * dY / iPointNeedAdd;
							ls_tmp.push_back(pt_tmp);
						}
					}
				}
			}
			else
			{
				ls_tmp.push_back(m_arrayPoint[i]);
			}
		}
		else
		{
			//ls_tmp.push_back(m_arrayPoint[i]); //this is not a point pen_down or pen_up
		}
	}
	
	/*
	for (std::list<Point2D>::iterator it = ls_tmp.begin() ; it != ls_tmp.end(); ++it)
	{
		printf("%.1f %.1f\n", it->x, it->y);
	}
	printf(" size of list %d \n", ls_tmp.size());
	*/

	// choose K from N point
	int i_nPoint, r, m;
	i_nPoint = ls_tmp.size();
	r = i_nPoint % K;
	m = (i_nPoint - r) / K;

	n = 0;

	if (r == 0)
	{
		std::list<Point2D>::iterator it = ls_tmp.begin();
		for (i = 0; i < m; ++i)
			++it;
		while(it != ls_tmp.end())
		{
			m_arrayPoint[n] = *it;
			++n;
			for (i = 0; i < m; ++i)
				++it;
		}
	}
	else
	{
		int p, t;
		p = K - r;
        t = 1 + (r - 1) * (m + 1);
		i = 1;
		for (std::list<Point2D>::iterator it = ls_tmp.begin() ; it != ls_tmp.end(); ++it)
		{
			if (i < t && (i - 1) % (m + 1)==0)
			{
				 m_arrayPoint[n] = *it;
				 ++n;
			}
            else if (i > t &&  (i-t) % m ==0)
			{
                 m_arrayPoint[n] = *it;
				 ++n;
			}
			++i;
		}
	}
	printf("duong duong duong %d \n", n);
	for (i = 0; i < n; ++i)
	{
		printf("%.1f %.1f\n", m_arrayPoint[i].x, m_arrayPoint[i].y);
	}
}

//#endif//_STROKE_H